package com.campus.campus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.api.util.UserContext;
import com.campus.campus.job.StaticData;
import com.campus.campus.job.dto.ElectricityUsageDTO;
import com.campus.campus.job.dto.TimeFeeDTO;
import com.campus.campus.job.entity.CampusCards;
import com.campus.campus.job.entity.TransactionDetail;
import com.campus.campus.job.entity.UtilityBills;
import com.campus.campus.mapper.*;
import com.campus.campus.service.IUtilityBillsService;
import com.campus.common.exception.ServiceException;
import com.campus.common.recharge.entity.RechargeRecords;
import com.campus.common.recharge.service.IRechargeRecordsService;
import com.campus.common.result.Result;
import com.campus.common.student.job.entity.Student;
import com.campus.common.student.mapper.StudentMapper;
import com.campus.common.user.entity.pojo.User;
import com.campus.common.user.mapper.AuthMapper;
import com.campus.campus.job.entity.UtilityConsumptionRecord;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 公用费用表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-11-18
 */
@Service
public class UtilityBillsServiceImpl extends ServiceImpl<UtilityBillsMapper, UtilityBills> implements IUtilityBillsService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private AuthMapper authMapper;

    @Autowired
    private CampusCardsMapper campusCardsMapper;

    @Autowired
    private UtilityBillsMapper utilityBillsMapper;

    @Autowired
    private IRechargeRecordsService rechargeRecordsService;

    @Autowired
    private UtilityConsumptionRecordMapper utilityConsumptionRecordMapper;

    @Autowired
    private StaticDataMapper staticDataMapper;

    @Autowired
    private TransacitionDetailMapper transacitionDetailMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result InsertElectronicFee(BigDecimal fee) {

        Student student = getStudent();

        CampusCards campusCards = campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>()
                .eq(CampusCards::getStudentId, student.getId()));

        if (campusCards.getBalance().compareTo(fee) < 0) {
            throw new RuntimeException("余额不足，无法支付电费");
        }

        UtilityBills utilityBillsOne = baseMapper.selectOne(new LambdaQueryWrapper<UtilityBills>().
                eq(UtilityBills::getCampusCardId, campusCards.getId())
                .eq(UtilityBills::getName, "电费"));
        UtilityBills utilityBills = new UtilityBills();
        if (utilityBillsOne != null) {
            utilityBillsOne.setFee(utilityBillsOne.getFee().add(fee));
            utilityBillsOne.setUpdateTime(LocalDateTime.now());
            BeanUtils.copyProperties(utilityBillsOne, utilityBills);
            int i = baseMapper.updateById(utilityBillsOne);
            if (i < 0) {
                return Result.fail("电费充值失败");
            }
        } else {
            utilityBills.setName("电费");
            utilityBills.setFee(fee);
            utilityBills.setUpdateTime(LocalDateTime.now());
            utilityBills.setCampusCardId(campusCards.getId());
            int i = baseMapper.insert(utilityBills);
            if (i < 0) {
                return Result.fail("电费充值失败");
            }
        }


        campusCards.setBalance(campusCards.getBalance().subtract(fee));
        int j = campusCardsMapper.updateById(campusCards);
        if (j < 0) {
            return Result.fail("电费充值失败");
        }

        //将充值费用存如交易明细表 transacitionDetailMapper
        TransactionDetail transactionDetail = new TransactionDetail();
        transactionDetail.setStudentId(student.getId());
        transactionDetail.setReduceAmount(fee);
        transactionDetail.setReduceDate(LocalDateTime.now());
        transactionDetail.setReduceSource("电费");
        int insert = transacitionDetailMapper.insert(transactionDetail);
        if (insert < 0) {
            return Result.fail("水费充值记录失败");
        }

        RechargeRecords rechargeRecords = new RechargeRecords();
        rechargeRecords.setFee(fee);
        rechargeRecords.setType("电费");
        rechargeRecords.setUtilityId(utilityBills.getId());
        rechargeRecordsService.insertRechargeRecords(rechargeRecords);
        return Result.success("电费充值成功");
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result InsertWaterFee(BigDecimal fee) {
        Student student = getStudent();

        CampusCards campusCards = campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>()
                .eq(CampusCards::getStudentId, student.getId()));

        if (campusCards.getBalance().compareTo(fee) < 0) {
            throw new RuntimeException("余额不足，无法支付水费");
        }

        UtilityBills utilityBillsOne = baseMapper.selectOne(new LambdaQueryWrapper<UtilityBills>()
                .eq(UtilityBills::getCampusCardId, campusCards.getId())
                .eq(UtilityBills::getName, "水费"));
        UtilityBills utilityBills = new UtilityBills();
        if (utilityBillsOne != null) {
            utilityBillsOne.setFee(utilityBillsOne.getFee().add(fee));
            utilityBillsOne.setUpdateTime(LocalDateTime.now());
            BeanUtils.copyProperties(utilityBillsOne, utilityBills);
            int i = baseMapper.updateById(utilityBillsOne);
            if (i < 0) {
                return Result.fail("水费充值失败");
            }
        } else {
            utilityBills.setName("水费");
            utilityBills.setFee(fee);
            utilityBills.setCampusCardId(campusCards.getId());
            utilityBills.setUpdateTime(LocalDateTime.now());
            int i = baseMapper.insert(utilityBills);
            if (i < 0) {
                return Result.fail("水费充值失败");
            }
        }
        //将充值费用存如交易明细表 transacitionDetailMapper
        TransactionDetail transactionDetail = new TransactionDetail();
        transactionDetail.setStudentId(student.getId());
        transactionDetail.setReduceAmount(fee);
        transactionDetail.setReduceDate(LocalDateTime.now());
        transactionDetail.setReduceSource("水费");
        int insert = transacitionDetailMapper.insert(transactionDetail);
        if (insert < 0) {
            return Result.fail("水费充值记录失败");
        }

        campusCards.setBalance(campusCards.getBalance().subtract(fee));
        int j = campusCardsMapper.updateById(campusCards);
        if (j < 0) {
            return Result.fail("水费充值失败");
        }
        RechargeRecords rechargeRecords = new RechargeRecords();
        rechargeRecords.setFee(fee);
        rechargeRecords.setType("水费");
        rechargeRecords.setUtilityId(utilityBills.getId());
        rechargeRecordsService.insertRechargeRecords(rechargeRecords);
        return Result.success("水费充值成功");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void subtratElectronicFee() {

        // 创建查询条件
        QueryWrapper<UtilityBills> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "电费")
                .orderByDesc("update_time")
                .select("DISTINCT campus_card_id", "id","name", "fee", "update_time");


        // 查询最新的电费记录
        List<UtilityBills> list = baseMapper.selectList(queryWrapper);

        if (list.size() > 0) {
            list.stream().forEach(utilityBills -> {
                // 设置随机数
                BigDecimal randomValue = BigDecimal.valueOf(Math.random() * 10); // 生成 0-10 的随机数

                // 更新记录
                utilityBills.setUpdateTime(LocalDateTime.now());
                utilityBills.setFee(utilityBills.getFee().subtract(randomValue)); // 减去随机数

                // 提交更新
                int result = baseMapper.updateById(utilityBills);

                if (result < 1) {
                    throw new RuntimeException("更新电费记录失败");
                }
                UtilityConsumptionRecord utilityConsumptionRecord = new UtilityConsumptionRecord();
                utilityConsumptionRecord.setDeductionAmount(randomValue);
                utilityConsumptionRecord.setCampusCardId(utilityBills.getCampusCardId());
                utilityConsumptionRecord.setUpdateTime(LocalDateTime.now());
                utilityConsumptionRecord.setDeductionTime(LocalDateTime.now());
                utilityConsumptionRecord.setType("电费");
                int i = utilityConsumptionRecordMapper.insert(utilityConsumptionRecord);
                if (i < 1) {
                    throw new RuntimeException("更新电费消耗记录失败");
                }
            });

        } else {
            throw new RuntimeException("未找到电费记录");
        }
    }


//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public void subtratElectronicFee() {
//        // 获取当前日期
//        LocalDate today = LocalDate.now();
//
//        // 创建查询条件
//        QueryWrapper<UtilityBills> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("name", "电费")
//                .orderByDesc("update_time")
//                .select("DISTINCT campus_card_id", "id", "name", "fee", "update_time");
//
//        // 查询最新的电费记录
//        List<UtilityBills> list = baseMapper.selectList(queryWrapper);
//
//        if (list.size() > 0) {
//            list.stream().forEach(utilityBills -> {
//                // 设置随机数
//                BigDecimal randomValue = BigDecimal.valueOf(Math.random() * 10); // 生成 0-10 的随机数
//
//                // 判断 `updateTime` 是否为今天
//                LocalDate updateDate = utilityBills.getUpdateTime().toLocalDate();
//                if (updateDate.isEqual(today)) {
//                    // 如果是今天，更新记录
//                    utilityBills.setUpdateTime(LocalDateTime.now());
//                    utilityBills.setFee(utilityBills.getFee().subtract(randomValue)); // 减去随机数
//
//                    // 提交更新
//                    int result = baseMapper.updateById(utilityBills);
//                    if (result < 1) {
//                        throw new RuntimeException("更新电费记录失败");
//                    }
//                } else {
//                    // 如果不是今天，插入新记录
//                    UtilityBills newBill = new UtilityBills();
//                    newBill.setName("电费");
//                    newBill.setCampusCardId(utilityBills.getCampusCardId());
//                    newBill.setFee(utilityBills.getFee().subtract(randomValue)); // 减去随机数
//                    newBill.setUpdateTime(LocalDateTime.now());
//                    int result = baseMapper.insert(newBill);
//                    if (result < 1) {
//                        throw new RuntimeException("插入新电费记录失败");
//                    }
//                }
//
//                // 插入电费消耗记录
//                UtilityConsumptionRecord utilityConsumptionRecord = new UtilityConsumptionRecord();
//                utilityConsumptionRecord.setDeductionAmount(randomValue);
//                utilityConsumptionRecord.setCampusCardId(utilityBills.getCampusCardId());
//                utilityConsumptionRecord.setUpdateTime(LocalDateTime.now());
//                utilityConsumptionRecord.setDeductionTime(LocalDateTime.now());
//                int i = utilityConsumptionRecordMapper.insert(utilityConsumptionRecord);
//                if (i < 1) {
//                    throw new RuntimeException("更新电费消耗记录失败");
//                }
//            });
//        } else {
//            throw new RuntimeException("未找到电费记录");
//        }
//    }


    @Override
    public void subtratWaterFee() {
        QueryWrapper<UtilityBills> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "水费")
                .orderByDesc("update_time")
                .select("DISTINCT campus_card_id","id", "name", "fee", "update_time");


        List<UtilityBills> list = baseMapper.selectList(queryWrapper);

        if (list.size() > 0) {
            list.stream().forEach(utilityBills -> {
                // 设置随机数
                BigDecimal randomValue = BigDecimal.valueOf(Math.random() * 10); // 生成 0-10 的随机数

                // 更新记录
                utilityBills.setUpdateTime(LocalDateTime.now());
                utilityBills.setFee(utilityBills.getFee().subtract(randomValue)); // 减去随机数

                // 提交更新
                int result = baseMapper.updateById(utilityBills);
                if (result < 1) {
                    throw new RuntimeException("更新水费记录失败");
                }
                UtilityConsumptionRecord utilityConsumptionRecord = new UtilityConsumptionRecord();
                utilityConsumptionRecord.setDeductionAmount(randomValue);
                utilityConsumptionRecord.setCampusCardId(utilityBills.getCampusCardId());
                utilityConsumptionRecord.setUpdateTime(LocalDateTime.now());
                utilityConsumptionRecord.setDeductionTime(LocalDateTime.now());
                utilityConsumptionRecord.setType("水费");
                int i = utilityConsumptionRecordMapper.insert(utilityConsumptionRecord);
                if (i < 1) {
                    throw new RuntimeException("更新电费消耗记录失败");
                }

            });

        } else {
            throw new RuntimeException("未找到水费记录");
        }
    }

    @Override
    public Result getElectricityStatistics(TimeFeeDTO timeFeeDTO) {
        Integer userId=UserContext.getUserId();
        Student student=studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getUserId,userId));
        if(Optional.ofNullable(student).isEmpty()){
            return Result.fail("未找到该学生信息");
        }
        CampusCards campusCards=campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>().eq(CampusCards::getStudentId,student.getId()));
        if(Optional.ofNullable(campusCards).isEmpty()){
            return Result.fail("未找到该学生校园卡信息");
        }

        if (timeFeeDTO.getTimeType().equals("month")) {

            String startTime = timeFeeDTO.getTime() + "-01";
            String endtimeNew = getEndTime(timeFeeDTO.getTime());

            List<ElectricityUsageDTO> list = utilityBillsMapper.getWeeklyUsageForMonth(startTime, endtimeNew, timeFeeDTO.getWay());

            return Result.success(list);
        } else if (timeFeeDTO.getTimeType().equals("week")) {
            // 获取当前日期作为结束时间
            LocalDate endDate = LocalDate.now();
            LocalDate nextDay = endDate.plusDays(1);

            // 计算七天前的日期作为开始时间
            LocalDate startDate = endDate.minusDays(6);
            // 格式化为字符串
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String startDateStr = startDate.format(formatter);
            String endDateStr = nextDay.format(formatter);
            List<ElectricityUsageDTO> list = staticDataMapper.getDailyUsageForWeek(startDateStr, endDateStr, timeFeeDTO.getWay(),campusCards.getId());
            return Result.success(list);
        }
        return Result.success(new ArrayList<>());

    }

    @Override
    public Result InsertCampusCard(BigDecimal fee) {

        int userId = UserContext.getUserId();
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>()
                .eq(Student::getUserId, userId));
        if (Optional.ofNullable(student).isEmpty()) {
            throw new ServiceException("未查询到该学生信息");
        }

        User user = authMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getId, userId));
        if (Optional.ofNullable(user).isEmpty()) {
            throw new ServiceException("未查询到该用户信息");
        }

        CampusCards campusCardsOne= campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>()
                .eq(CampusCards::getStudentId, student.getId()));

        CampusCards campusCards = new CampusCards();
        if(Optional.ofNullable(campusCardsOne).isEmpty()){
            campusCards.setBalance(fee);
            campusCards.setStudentId(student.getId());
            int i = campusCardsMapper.insert(campusCards);
            if (i < 0) {
                return Result.fail("校园卡充值失败");
            }
        }else{
            BeanUtils.copyProperties(campusCardsOne,campusCards);
            campusCards.setBalance(campusCardsOne.getBalance().add(fee));
            int i = campusCardsMapper.updateById(campusCards);
            if (i < 0) {
                return Result.fail("校园卡充值失败");
            }
        }
        RechargeRecords rechargeRecords = new RechargeRecords();
        rechargeRecords.setFee(fee);
        rechargeRecords.setType("校园卡");
        rechargeRecords.setUtilityId(-1);
        rechargeRecordsService.insertRechargeRecords(rechargeRecords);
        return Result.success();
    }

    @Override
    public Result getElectricity() {
        int userId = UserContext.getUserId();
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>()
                .eq(Student::getUserId, userId));
        if (Optional.ofNullable(student).isEmpty()) {
            throw new ServiceException("未查询到该学生信息");
        }
        CampusCards campusCards = campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>().eq(CampusCards::getStudentId, student.getId()));

        if (campusCards.equals(null)) {
            return Result.fail("未查询到该学生校园卡信息");
        }

        UtilityBills utilityBills = utilityBillsMapper.selectOne(new LambdaQueryWrapper<UtilityBills>()
                .eq(UtilityBills::getCampusCardId, campusCards.getId())
                .eq(UtilityBills::getName, "电费"));

        return Result.success(utilityBills.getFee());
    }

    @Override
    public Result getWaterTotalFee(String type) {
        int userId = UserContext.getUserId();
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>()
                .eq(Student::getUserId, userId));
        if (Optional.ofNullable(student).isEmpty()) {
            throw new ServiceException("未查询到该学生信息");
        }
        CampusCards campusCards = campusCardsMapper.selectOne(new LambdaQueryWrapper<CampusCards>().eq(CampusCards::getStudentId, student.getId()));

        if (campusCards.equals(null)) {
            return Result.fail("未查询到该学生校园卡信息");
        }

        // 获取今年年初的时间
        LocalDateTime startOfYear = LocalDateTime.of(LocalDateTime.now().getYear(), 1, 1, 0, 0, 0);
        // 获取明年年初的时间
        LocalDateTime startOfNextYear = startOfYear.plusYears(1);

        // 格式化为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String startTimeFormatted = startOfYear.format(formatter);
        String endTimeFormatted = startOfNextYear.format(formatter);

        BigDecimal total=staticDataMapper.getTotal(startTimeFormatted,endTimeFormatted,type);

        return Result.success(total);
    }


    private Student getStudent() {
        int userId = UserContext.getUserId();
        Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>()
                .eq(Student::getUserId, userId));
        if (Optional.ofNullable(student).isEmpty()) {
            throw new ServiceException("未查询到该学生信息");
        }

        User user = authMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getId, userId));
        if (Optional.ofNullable(user).isEmpty()) {
            throw new ServiceException("未查询到该用户信息");
        }
        return student;
    }


    public static String getEndTime(String endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        YearMonth yearMonth = YearMonth.parse(endTime, formatter);

        LocalDate lastDayOfMonth = yearMonth.atEndOfMonth();

        String end = lastDayOfMonth.format(DateTimeFormatter.ISO_LOCAL_DATE);

        return end;
    }


}
